__DefGroup DALU : [ALL]
  __Encoding
    field<12,  3> Pred pg = PT;
    field<15,  1> PModi pg.not = False;

__DefGroup D_ARITH : [DALU]
  __Encoding
    field<16,  8> Reg rd;
    field<24,  8> Reg ra;

    field<72,  1> SignModi ra.neg = False;
    field<73,  1> SignModi ra.abs = False;

    field<78,  2> FPRound rnd = RN;

//DADD Begin
__DefOptype DADD : [D_ARITH]
  __Encoding
    field< 0,  8> Optype optype == DADD;
  
  __Syntax
```asm          
DADD{.rnd} Rd, {-}{|}Ra{|}, {-}{|}SrcB{|}      $sched $req $wsb ;

.rnd = {.RN*, .RP, .RM, .RZ}
```

  __Description
执行2个输入双精度浮点数的加法，即Rd = Ra + SrcB。

所有操作数都必须是64bit的双精度浮点数。

  __OperandInfo
Ra和Rd必须来源于GPR。

SrcB的来源可以是GPR、UR、F64Imm或cmem。

  __ModifierInfo
.rnd可取.RN（默认值，可省略）、.RP、.RM和.RZ，表示计算结果的舍入模式：

| .rnd  | 舍入模式 |
|:--:|:---|
|.RN | 尾数四舍五入 |
|.RP | 尾数向正无穷方向舍入 |
|.RM | 尾数向负无穷方向舍入 |
|.RZ | 尾数向零（原点）舍入 |

  __Semantics
```asm
DADD.rnd Rd, Ra, SrcB:
    // 计算舍入前的精确求和
    t = Ra + SrcB;
    // 舍入到双精度浮点数可表示的值
    Rd = roundToF64(t, .rnd);
```

浮点加法中的特殊值，遵守
[IEEE 754浮点加法乘法特殊规则](IEEE754浮点加法乘法特殊规则.md#一加法运算特殊值处理)。

DADD指令可能产生NAN，对NAN的处理规则参考[浮点数NAN处理规则](浮点数NAN处理规则.md#64bit浮点数指令的处理规则)。

  __Examples
```asm
DADD    R[0:1],   R[2:3], -R[4:5] ;
DADD.RZ R[0:1], |R[2:3]|,   -0.25 ;
```
  __Simulation
      vd = DADD(va, vb);

__DefOpcode DADD_RR : [DADD]
  __Encoding
    field< 8,  4> SType stype == RR;

    field<32,  8> Reg rb;

    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;

  __OperandInfo
    InList<pg, ra, rb>;
    OutList<rd>;
    Order<pg, rd, ra, rb>;
    Bitwidth<ra> = 64;
    Bitwidth<rb> = 64;
    Bitwidth<rd> = 64;

  __Exception

__DefOpcode DADD_RU : [DADD]
  __Encoding
    field< 8,  4> SType stype == RU;

    field<32,  6> UReg urb;

    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;

  __OperandInfo
    InList<pg, ra, urb>;
    OutList<rd>;
    Order<pg, rd, ra, urb>;
    Bitwidth<ra> = 64;
    Bitwidth<urb> = 64;
    Bitwidth<rd> = 64;

__DefOpcode DADD_RI : [DADD]
  __Encoding
    field< 8,  4> SType stype == RI;

    field<32, 32> F64Imm vb;

  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<ra> = 64;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 64;

__DefOpcode DADD_RC : [DADD]
  __Encoding
    field< 8,  4> SType stype == RC;

    field<32, 22> CMem vb;

    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;

  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<ra> = 64;
    Bitwidth<vb> = 64;
    Bitwidth<rd> = 64;

__DefOptype DMUL : [D_ARITH]
  __Encoding
    field< 0,  8> Optype optype == DMUL;

  __Syntax
```asm          
DMUL{.rnd} Rd, {-}{|}Ra{|}, {-}{|}SrcB{|}      $sched $req $wsb ;

.rnd = {.RN*, .RP, .RM, .RZ}
```

  __Description
执行2个输入双精度浮点数的乘法，即Rd = Ra * SrcB。

所有操作数都必须是64bit的双精度浮点数。

  __OperandInfo
Ra和Rd必须来源于GPR。

SrcB的来源可以是GPR、UR、cmem或F64Imm。

  __ModifierInfo
.rnd可取.RN（默认值，可省略）、.RP、.RM和.RZ，表示计算结果的舍入模式：

| .rnd  | 舍入模式 |
|:--:|:---|
|.RN | 尾数四舍五入 |
|.RP | 尾数向正无穷方向舍入 |
|.RM | 尾数向负无穷方向舍入 |
|.RZ | 尾数向零（原点）舍入 |

  __Semantics
```asm
DMUL.rnd Rd, Ra, SrcB:
    // 计算舍入前的精确乘积
    t = Ra * SrcB;
    // 舍入到双精度浮点数可表示的值
    Rd = roundToF64(t, .rnd);
```

浮点乘法中的特殊值，在遵守
[IEEE 754浮点加法乘法特殊规则](IEEE754浮点加法乘法特殊规则.md#二乘法运算特殊值处理)
的基础上，根据各个修饰符含义进行处理。

DMUL指令的乘法结果可能产生NAN，，对NAN的处理规则参考[浮点数NAN处理规则](浮点数NAN处理规则.md#64bit浮点数指令的处理规则)

  __Examples
```asm
DMUL    R[0:1],   R[2:3], -R[4:5] ;
DMUL.RZ R[0:1], |R[2:3]|,   -0.25 ;
```

  __Simulation
      vd = DMUL(va, vb);

__DefOpcode DMUL_RR : [DMUL]
  __Encoding
    field< 8,  4> SType stype == RR;

    field<32,  8> Reg rb;

    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;

  __Exception


  __OperandInfo
    InList<pg, ra, rb>;
    OutList<rd>;
    Order<pg, rd, ra, rb>;
    Bitwidth<ra> = 64;
    Bitwidth<rb> = 64;
    Bitwidth<rd> = 64;

__DefOpcode DMUL_RU : [DMUL]
  __Encoding
    field< 8,  4> SType stype == RU;

    field<32,  6> UReg urb;

    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;
  __OperandInfo
    InList<pg, ra, urb>;
    OutList<rd>;
    Order<pg, rd, ra, urb>;
    Bitwidth<ra> = 64;
    Bitwidth<urb> = 64;
    Bitwidth<rd> = 64;

__DefOpcode DMUL_RI : [DMUL]
  __Encoding
    field< 8,  4> SType stype == RI;
    field<32, 32> F64Imm vb;

  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<ra> = 64;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 64;

__DefOpcode DMUL_RC : [DMUL]
  __Encoding
    field< 8,  4> SType stype == RC;

    field<32, 22> CMem vb;

    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;

  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<ra> = 64;
    Bitwidth<vb> = 64;
    Bitwidth<rd> = 64;

__DefOptype DFMA : [D_ARITH]
  __Encoding
    field< 0,  8> Optype optype == DFMA;

  __Syntax
```asm          
DFMA{.rnd} Rd, {-}{|}Ra{|}, {-}{|}SrcB{|}, {-}{|}SrcC{|}      $sched $req $wsb ;

.rnd = {.RN*, .RP, .RM, .RZ}
```

  __Description
执行3个输入双精度浮点数的融合乘加，即Rd = Ra * SrcB + SrcC。

计算过程等价于：
- 先以全精度计算prod = Ra * SrcB的乘积，结果不发生舍入
- 再计算prod + SrcC的和，结果舍入到双精度浮点数的可表示值

  __OperandInfo
Ra和Rd必须来源于GPR。

SrcB和SrcC的来源组合包括：
| SrcB | SrcC | 
|:--:|:--:|
| GPR | GPR |
| GPR | F64Imm |
| F64Imm | GPR |
| GPR | UR |
| UR | GPR |
| GPR | cmem |
| cmem | GPR |

  __ModifierInfo
.rnd可取.RN（默认值，可省略）、.RP、.RM和.RZ，表示计算结果的舍入模式：

| .rnd  | 舍入模式 |
|:--:|:---|
|.RN | 尾数四舍五入 |
|.RP | 尾数向正无穷方向舍入 |
|.RM | 尾数向负无穷方向舍入 |
|.RZ | 尾数向零（原点）舍入 |

  __Semantics
```asm
DFMA.rnd Rd, Ra, SrcB, SrcC:
    // 计算精确乘积
    prod = Ra * SrcB;
    // 计算精确求和
    d = prod + SrcC;
    // 舍入到双精度浮点数可表示的值
    Rd = roundToF64(d, .rnd);
```

浮点乘加中的特殊值，在遵守
[IEEE 754浮点加法乘法特殊规则](IEEE754浮点加法乘法特殊规则.md)
的基础上，根据各个修饰符含义进行处理。

DFMA指令的计算结果可能产生NAN，对NAN的处理规则参考[浮点数NAN处理规则](浮点数NAN处理规则.md#64bit浮点数指令的处理规则)。

特别的，在按照该规则的[输入操作数含有NAN](浮点数NAN处理规则.md#输入操作数含有nan)处理输入NAN时，按照SrcB->SrcC->Ra的顺序选择用于生成QNAN的输入NAN操作数。

  __Examples
```asm
DFMA    R[0:1],   R[2:3], -R[4:5], RZ     ;
DFMA.RZ R[0:1], |R[2:3]|,   -0.25, R[0:1] ;
```

  __Simulation
      vd = fmaf(va, vb, vc);

__DefOpcode DFMA_RRR : [DFMA]
  __Encoding
    field< 8,  4> SType stype == RRR;

    field<32,  8> Reg rb;
    field<64,  8> Reg rc;

    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;
    field<74,  1> SignModi rc.neg = False;
    field<75,  1> SignModi rc.abs = False;

  __OperandInfo
    InList<pg, ra, rb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, rc>;
    Bitwidth<ra> = 64;
    Bitwidth<rb> = 64;
    Bitwidth<rc> = 64;
    Bitwidth<rd> = 64;

__DefOpcode DFMA_RRI : [DFMA]
  __Encoding
    field< 8,  4> SType stype == RRI;

    field<32, 32> F64Imm vc;
    field<64,  8> Reg rb;

    field<74,  1> SignModi rb.neg = False;
    field<75,  1> SignModi rb.abs = False;

  __OperandInfo
    InList<pg, ra, rb, vc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, vc>;
    Bitwidth<ra> = 64;
    Bitwidth<rb> = 64;
    Bitwidth<vc> = 32;
    Bitwidth<rd> = 64;

__DefOpcode DFMA_RIR : [DFMA]
  __Encoding
    field< 8,  4> SType stype == RIR;

    field<32, 32> F64Imm vb;
    field<64,  8> Reg rc;

    field<74,  1> SignModi rc.neg = False;
    field<75,  1> SignModi rc.abs = False;

  __OperandInfo
    InList<pg, ra, vb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, vb, rc>;
    Bitwidth<ra> = 64;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 64;
    Bitwidth<rd> = 64;

__DefOpcode DFMA_RRU : [DFMA]
  __Encoding
    field< 8,  4> SType stype == RRU;

    field<32,  6> UReg urc;
    field<64,  8> Reg rb;

    field<96,  1> SignModi urc.neg = False;
    field<97,  1> SignModi urc.abs = False;
    field<74,  1> SignModi rb.neg = False;
    field<75,  1> SignModi rb.abs = False;

  __OperandInfo
    InList<pg, ra, rb, urc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, urc>;
    Bitwidth<ra> = 64;
    Bitwidth<rb> = 64;
    Bitwidth<urc> = 64;
    Bitwidth<rd> = 64;

__DefOpcode DFMA_RUR : [DFMA]
  __Encoding
    field< 8,  4> SType stype == RUR;

    field<32,  6> UReg urb;
    field<64,  8> Reg rc;

    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;
    field<74,  1> SignModi rc.neg = False;
    field<75,  1> SignModi rc.abs = False;

  __OperandInfo
    InList<pg, ra, urb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, urb, rc>;
    Bitwidth<ra> = 64;
    Bitwidth<urb> = 64;
    Bitwidth<rc> = 64;
    Bitwidth<rd> = 64;

__DefOpcode DFMA_RRC : [DFMA]
  __Encoding
    field< 8,  4> SType stype == RRC;
    field<32, 22> CMem vc;
    field<64,  8> Reg rb;
    field<96,  1> SignModi vc.neg = False;
    field<97,  1> SignModi vc.abs = False;
    field<74,  1> SignModi rb.neg = False;
    field<75,  1> SignModi rb.abs = False;

  __OperandInfo
    InList<pg, ra, rb, vc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, vc>;
    Bitwidth<ra> = 64;
    Bitwidth<rb> = 64;
    Bitwidth<vc> = 64;
    Bitwidth<rd> = 64;

__DefOpcode DFMA_RCR : [DFMA]
  __Encoding
    field< 8,  4> SType stype == RCR;

    field<32, 22> CMem vb;

    field<64,  8> Reg rc;

    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;
    field<74,  1> SignModi rc.neg = False;
    field<75,  1> SignModi rc.abs = False;

  __OperandInfo
    InList<pg, ra, vb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, vb, rc>;
    Bitwidth<ra> = 64;
    Bitwidth<vb> = 64;
    Bitwidth<rc> = 64;
    Bitwidth<rd> = 64;

__DefOptype DMNMX : [DALU]
  __Encoding
    field< 0,  8> Optype optype == DMNMX;

    field<98, 3> Pred pp;
    field<101, 1> PModi pp.not = False;

    field<16,  8> Reg rd;
    field<24,  8> Reg ra;

    field<72,  1> SignModi ra.neg = False;
    field<73,  1> SignModi ra.abs = False;

  __Syntax
```asm
DMNMX Rd, {-}{|}Ra{|}, {-}{|}SrcB{|}, {!}pp      $sched $req $wsb ;
```

  __Description
根据谓词pp，选取输入双精度浮点数的最大/最小值输出。

  __OperandInfo
Rd和Ra必须来源于GPR。

SrcB可以来源于GPR、UR、F64Imm或cmem。

pp必须来源于PR，且可以添加一个逻辑非（!）前缀，表示取反作为操作数。

  __Semantics
```asm
DMNMX Rd, Ra, SrcB, pp:
    // 正确处理输入含NAN的情况：
    if (isNAN(Ra) == true || isNAN(srcB) == true) {
        // 试图返回另一个不是NAN的数
        if (isNAN(Ra) == false) {
            Rd = Ra;
        } else if (isNAN(SrcB) == false) {
            Rd = SrcB;
        // 输入都是NAN，根据SrcB生成一个QNAN返回
        } else {
            Rd = QNAN(SrcB);
        }
    // 对正常输入，选择Ra和SrcB中较小/较大的那个作为输出
    } else {
        Rd = pp ? max(Ra, SrcB) : min(Ra, SrcB);
    }
```

若参与比较的2个输入绝对值均为0.0，则按照+0.0 > -0.0选取输出。

这里需要着重指出DMNMX处理输入NAN时的行为：
- 若输入Ra和SrcB有且仅有一个NAN，则输出不是NAN的另外一个操作数
- 若Ra和SrcB都是NAN，则按照[浮点数NAN处理规则](浮点数NAN处理规则.md#输入操作数含有NAN)中的规则产生输出

  __Examples
```asm
DMNMX R[0:1], -|R[2:3]|, -|R2|, !PT ;
DMNMX R[0:1],    R[2:3], 0.125, !P1 ;
```

__DefOpcode DMNMX_RR : [DMNMX]
  __Encoding
    field< 8,  4> SType stype == RR;

    field<32,  8> Reg rb;

    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;

  __OperandInfo
    InList<pg, ra, rb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, rb, pp>;
    Bitwidth<ra> = 64;
    Bitwidth<rb> = 64;
    Bitwidth<rd> = 64;

__DefOpcode DMNMX_RU : [DMNMX]
  __Encoding
    field< 8,  4> SType stype == RU;

    field<32,  6> UReg urb;

    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;

  __OperandInfo
    InList<pg, ra, urb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, urb, pp>;
    Bitwidth<ra> = 64;
    Bitwidth<urb> = 64;
    Bitwidth<rd> = 64;

__DefOpcode DMNMX_RI : [DMNMX]
  __Encoding
    field< 8,  4> SType stype == RI;

    field<32, 32> F64Imm vb;

  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<ra> = 64;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 64;

__DefOpcode DMNMX_RC : [DMNMX]
  __Encoding
    field< 8,  4> SType stype == RC;

    field<32, 22> CMem vb;

    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;

  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<ra> = 64;
    Bitwidth<vb> = 64;
    Bitwidth<rd> = 64;

__DefOptype DSETP : [DALU]
  __Encoding
    field< 0,  8> Optype optype == DSETP;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not=False;
    field<106,  3> Pred pu;
    field<109,  3> Pred pv = PT;

    field<24,  8> Reg ra;
    field<72,  1> SignModi ra.neg = False;
    field<73,  1> SignModi ra.abs = False;

    field<84,  2> LOPOp lop;
    field<86,  4> FCMPOp cmp;
  
  __Syntax
```asm          
DSETP.cmp.lop pu, {pv,} {-}{|}Ra{|}, {-}{|}SrcB{|}{, {!}pp}      $sched $req $wsb ;

.cmp = {.EQ, .NE, .LT, .LE, .GT, .GE, .EQU, .NEU, .LTU, .LEU, .GTU, .GEU, .NAN, .NUM}
.lop = {.AND*, .OR, .XOR}
```

  __Description
对2个输入双精度浮点数进行指定的算术比较，将比较结果（布尔值）与一个额外的输入谓词进行指定的布尔运算，得到输出。

  __OperandInfo
Ra只能来源于GPR。

SrcB可以是GPR、UR、F64Imm或cmem。

输出操作数pu、pv，输入操作数pp均为谓词，来源只能是PR。

输出操作数pv的默认值是PT（可以省略），表示舍弃pv的计算结果。

输入操作数pp的默认值是PT（可以省略），且可添加一个逻辑非(!)前缀，表示取反作为操作数。

  __ModifierInfo
.cmp决定对Ra、SrcB所作的算术比较，包含14种可取值。按照对输入NAN时的处理方式，.cmp的前12种可取值被分为ordered比较和unordered比较两类：

| ordered比较 | unordered比较 | 输入不含NAN时的语义 |
|:--:|:--:|:--:|
| .EQ | .EQU | == |
| .NE | .NEU | != |
| .LT | .LTU | <  |
| .LE | .LEU | <= |
| .GT | .GTU | >  |
| .GE | .GEU | >= |

二者的区别在于，当比较的两个操作数中至少含有1个NAN时：
- ordered比较：返回false
- unordered比较：返回true

.cmp的最后2种可取值.NAN和.NUM的含义如下：
- .NAN：参与比较的2个输入至少一个是NAN时，结果为true，否则为false
- .NUM：参与比较的2个输入都不是NAN时，结果为true，否则为false

.lop决定了将Ra、SrcB的比较结果与输入布尔值（操作数pp）进行何种布尔运算：

| .lop | 功能 |
|:--:|:--:|
| .AND | && |
| .OR  | \|\| |
| .XOR | ^ |

  __Semantics
```asm
DSETP.cmp.lop pu, pv, Ra, SrcB, pp:
    // 比较2个输入操作数Ra与SrcB
    t = Ra cmp SrcB ? true : false;
    // 根据lop对t与pp进行布尔运算
    pu = t lop pp;
    pv = (!t) lop pp;
```

  __Examples
```asm
DSETP.LE     P0,       R[4:5] , R[6:7]      ;
DSETP.GTU.OR P0, P1, -|R[6:7]|,     -1, !PT ;
```

__DefOpcode DSETP_RR : [DSETP]
  __Encoding
    field< 8,  4> SType stype == RR;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not = False;

    field<32,  8> Reg rb;
    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;

  __OperandInfo
    InList<pg, ra, rb, pp>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, rb, pp>;
    Bitwidth<ra> = 64;
    Bitwidth<rb> = 64;

__DefOpcode DSETP_RU : [DSETP]
  __Encoding
    field< 8,  4> SType stype == RU;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not = False;

    field<32,  6> UReg urb;
    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;

  __OperandInfo
    InList<pg, ra, urb, pp>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, urb, pp>;
    Bitwidth<ra> = 64;
    Bitwidth<urb> = 64;

__DefOpcode DSETP_RI : [DSETP]
  __Encoding
    field< 8,  4> SType stype == RI;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not = False;

    field<32, 32> F64Imm vb;

  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, vb, pp>;
    Bitwidth<ra> = 64;
    Bitwidth<vb> = 32;

__DefOpcode DSETP_RC : [DSETP]
  __Encoding
    field< 8,  4> SType stype == RC;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not = False;

    field<32, 22> CMem vb;

    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, vb, pp>;
    Bitwidth<ra> = 64;
    Bitwidth<vb> = 64;